package com.lzl.soaware.frame.aop;

import com.lzl.soaware.db.service.DbService;
import com.lzl.soaware.frame.annotation.Soaware;
import com.lzl.soaware.frame.model.AbstractPo;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.*;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.beans.factory.annotation.Autowired;

@Aspect
public class SoawareAspect {

    @Autowired
    DbService dbService;

    /**
     * 此处的切点是注解的方式，也可以用包名的方式达到相同的效果
     * '@Pointcut("execution(* com.wwj.springboot.service.impl.*.*(..))")'
     */
    @Pointcut("@annotation(com.lzl.soaware.frame.annotation.Soaware)")
    public void operation(){}


    /**
     * 环绕增强，相当于MethodInterceptor
     */
    @Around("operation()")
    public Object doAround(ProceedingJoinPoint joinPoint) throws Throwable {
        Object res = null;
        long time = System.currentTimeMillis();
        try {
            res =  joinPoint.proceed();
            time = System.currentTimeMillis() - time;
            return res;
        } finally {
            try {
                //方法执行完成后增加持久化操作
                addOperationDb(joinPoint,res,time);
            }catch (Exception e){
                System.out.println("LogAspect 操作失败：" + e.getMessage());
                e.printStackTrace();
            }
        }
    }

    private void addOperationDb(JoinPoint joinPoint, Object res, long time){
        MethodSignature signature = (MethodSignature)joinPoint.getSignature();
        Soaware annotation = signature.getMethod().getAnnotation(Soaware.class);
        if (annotation != null) {
            Class<?> poType = annotation.po();
            try {
                Object obj = poType.newInstance();
                if (obj instanceof AbstractPo) {
                    AbstractPo  po = (AbstractPo) obj;
                    po.execute(joinPoint, res);
                    po.handleDb(dbService);
                }

            } catch (InstantiationException e) {
                e.printStackTrace();
            } catch (IllegalAccessException e) {
                e.printStackTrace();
            }
        }
    }



    @Before("operation()")
    public void doBeforeAdvice(JoinPoint joinPoint){
        System.out.println("进入方法前执行.....");

    }

    /**
     * 处理完请求，返回内容
     * @param ret
     */
    @AfterReturning(returning = "ret", pointcut = "operation()")
    public void doAfterReturning(Object ret) {
        System.out.println("方法的返回值 : " + ret);
    }

    /**
     * 后置异常通知
     */
    @AfterThrowing(value = "operation()", throwing = "e")
    public void throwss(JoinPoint jp, Exception e){
        System.out.println("方法发生异常:" + e.getMessage());
    }


    /**
     * 后置最终通知,final增强，不管是抛出异常或者正常退出都会执行
     */
    @After("operation()")
    public void after(JoinPoint jp){

        System.out.println("方法最后执行.....");
    }
}
